package com.ruoyi.bizsys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.bizsys.domain.LoanIou;
import com.ruoyi.bizsys.domain.LoanOrder;
import com.ruoyi.bizsys.mapper.LoanIouMapper;
import com.ruoyi.bizsys.service.ILoanIouService;
import com.ruoyi.bizsys.service.ILoanOrderService;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.bizsys.vo.LoanIouVo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 贷款借据Service业务层处理
 *
 * @author african-loan
 * @date 2021-12-30
 */
@Service
public class LoanIouServiceImpl extends ServiceImpl<LoanIouMapper, LoanIou> implements ILoanIouService {

    @Autowired
    private ILoanOrderService loanOrderService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private LoanIouMapper loanIouMapper;

    /**
     * 查询贷款借据
     *
     * @param id 贷款借据ID
     * @return 贷款借据
     */
    @Override
    public LoanIou selectLoanIouById(Long id) {
        return this.getById(id);
    }

    /**
     * 查询贷款借据列表
     *
     * @param loanIou 贷款借据
     * @return 贷款借据
     */
    @Override
    public List<LoanIou> selectLoanIouList(LoanIou loanIou) {
        return this.list(new QueryWrapper<>(loanIou).last("order by id desc"));
    }


    /**
     * 后台用
     * @param loanIou 贷款借据
     * @return
     */
    @Override
    public List<LoanIou> getList(LoanIou loanIou) {
        if(loanIou.getParams().entrySet().size() > 0){
            return this.list(new QueryWrapper<>(loanIou).ge("create_time",loanIou.getParams().get("beginTime")).lt("create_time",loanIou.getParams().get("endTime")).last("order by id desc"));
        }
        return this.list(new QueryWrapper<>(loanIou).last("order by id desc"));
    }

    /**
     * 入催任务，查询正常的借据列表
     *
     * @param custNo
     * @param repayDate
     * @return
     */
    @Override
    public List<LoanIou> findNormalLoanIous(String custNo, String repayDate) {
        return loanIouMapper.findNormalLoanIous(custNo, repayDate);
    }

    /**
     * 新增贷款借据
     *
     * @param loanIou 贷款借据
     * @return 结果
     */
    @Override
    public int insertLoanIou(LoanIou loanIou) {
        loanIou.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insert(loanIou);
    }

    /**
     * 修改贷款借据
     *
     * @param loanIou 贷款借据
     * @return 结果
     */
    @Override
    public int updateLoanIou(LoanIou loanIou) {
        loanIou.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(loanIou);
    }

    /**
     * 批量删除贷款借据
     *
     * @param ids 需要删除的贷款借据ID
     * @return 结果
     */
    @Override
    public int deleteLoanIouByIds(Long[] ids) {
        return baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除贷款借据信息
     *
     * @param id 贷款借据ID
     * @return 结果
     */
    @Override
    public int deleteLoanIouById(Long id) {
        return baseMapper.deleteById(id);
    }

    @Override
    public List<String> selRepaymentNoApplyAgain() {
        List<LoanIou> loanIous = baseMapper.selRepaymentNoApplyAgain();
        List<String> objects = new ArrayList<>();
        loanIous.forEach(e -> {
            //剔除之后的订单 更大
            int loanOrderCount = loanOrderService.isBiggerByCustNo(e.getCustNo(), e.getLoanSerialNo());
            if (loanOrderCount == 0) {
                objects.add(e.getCustNo());
            }
        });
        return objects;
    }

    @Override
    public int overdueIouCount(String custNo) {
        QueryWrapper<LoanIou> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cust_no", custNo);
        queryWrapper.eq("iou_status", 2);
        String compare = configService.selectConfigByKey("raiseLimit_overdueDays");
        if (Func.isNotEmpty(compare)) {
            compare = compare.replaceAll("\\{", "<").
                    replaceAll("}", ">").
                    replaceAll("overdueDays", "to_days(now()) - to_days(repay_date)");
        }
        return baseMapper.overdueIouCount(custNo, compare);
    }

    @Override
    public List<String> selRepaymentNoApplyAgainMoreThan10() {
        List<LoanIou> loanIous = baseMapper.selRepaymentNoApplyAgainMoreThan10();
        List<String> objects = new ArrayList<>();
        loanIous.forEach(e -> {
            //剔除之后的订单 更大
            int loanOrderCount = loanOrderService.isBiggerByCustNo(e.getCustNo(), e.getLoanSerialNo());
            if (loanOrderCount == 0) {
                objects.add(e.getCustNo());
            }
        });
        return objects;
    }

    @Override
    public List<LoanIouVo> selectIouTask(String intervalHours) {
        return loanIouMapper.selectIouTask(intervalHours);
    }

    @Override
    public int getHaveDeIou(String custNo) {
        return Optional.ofNullable(loanIouMapper.getHaveDeIou(custNo)).orElse(0);
    }

    @Override
    public List<LoanIou> getDeferredTotalDay(String custNo) {
        return loanIouMapper.selectList(new QueryWrapper<LoanIou>().eq("cust_no", custNo).eq("state", 1));
    }

    @Override
    public String selectMinDueData(String custNo) {
        return loanIouMapper.selectMinDueData(custNo);
    }

    @Override
    public String selectzdzhangdanricha(String custNo) {
        return loanIouMapper.selectzdzhangdanricha(custNo);
    }

    @Override
    public String getwhdwsjcha2(String custNo) {
        return loanIouMapper.getwhdwsjcha2(custNo);
    }

    @Override
    public LoanIou getLoanIouNotSettled(String custNo) {
        return loanIouMapper.getLoanIouNotSettled(custNo);
    }

    @Override
    public List<String> getDueIouCustNo() {

        String overdueDays = configService.selectConfigByKey("wallet_debit_overdue_days");
        if (StringUtils.isBlank(overdueDays)) {
            overdueDays = "2";
        }

        LambdaQueryWrapper<LoanIou> queryWrapper = new LambdaQueryWrapper<LoanIou>();
        queryWrapper.eq(LoanIou::getIouStatus, LoanIou.LOAN_IOU_STATUS_OVERDUE);
        queryWrapper.eq(LoanIou::getState, BizConstants.BIZ_STATUS_1);
        queryWrapper.apply("datediff(now(), IF(is_deferred = 1, deferred_repay_date, repay_date)) >= " + overdueDays);
        List<LoanIou> loanIouList = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(loanIouList)) {
            return new ArrayList<>();
        }

        return loanIouList.stream().map(LoanIou::getCustNo).collect(Collectors.toList());

//        return this.list(new QueryWrapper<LoanIou>().select("DISTINCT cust_no").
//                        .eq("iou_status", BizConstants.LOAN_IOU_STATUS_OVERDUE)
//                        .or().eq("repay_date", DateFormatUtils.format(new Date(), DateUtils.YYYY_MM_DD_SLASH))
//                        .or().eq("deferred_repay_date", DateFormatUtils.format(new Date(), DateUtils.YYYY_MM_DD_SLASH))
//                .eq("state", BizConstants.BIZ_STATUS_1)).stream().map(LoanIou::getCustNo).collect(Collectors.toList());
    }

    @Override
    public List<LoanIou> getCustDueIou(String custNo) {
        return this.list(new QueryWrapper<LoanIou>().eq("cust_no", custNo).in("iou_status", LoanIou.LOAN_IOU_STATUS_NORMAL, LoanIou.LOAN_IOU_STATUS_OVERDUE).eq("state", BizConstants.BIZ_STATUS_1).orderByAsc("id"));
    }

    @Override
    public List<LoanIou> getCardWithholdIouByCustNo(String custNo) {
        return baseMapper.getCardWithholdIouByCustNo(custNo);
    }

    @Override
    public LoanIou getLatestOne(String custNo) {
        return getOne(new QueryWrapper<LoanIou>().eq("cust_no", custNo).last("order by id desc limit 1"));
    }

    @Override
    public LoanIou getLoanIouDetail(LoanIou loanIouQuery) {
        return baseMapper.getLoanIouDetail(loanIouQuery);
    }

    @Override
    public LoanIou getLoanIouByLoanSerialNo(String loanSerialNo) {
        return baseMapper.getLoanIouByLoanSerialNo(loanSerialNo);
    }

    @Override
    public List<LoanIou> getListByCustNo(String custNo) {
        QueryWrapper<LoanIou> eq = new QueryWrapper<LoanIou>().eq("cust_no", custNo).eq("state", 1);
        return list(eq);
    }

    @Override
    public boolean initializeIOUByOrder(LoanOrder loanOrder) {
        LoanIou loanIou = new LoanIou();
        BeanUtils.copyProperties(loanOrder, loanIou);
        loanIou.setLoanPrincipal(loanOrder.getLoanAmt());
        loanIou.setLoanInterest(loanOrder.getInterestAmt());
        loanIou.setIouStatus(LoanIou.LOAN_IOU_STATUS_NORMAL);
        loanIou.setRepayDate(DateUtils.getFewDay(loanOrder.getPeriodNum()));
        loanIou.setServiceRate(loanOrder.getServiceFeeRate());
        loanIou.setRemark("");
        loanIou.setCreateTime(new Date());
        loanIou.setUpdateTime(new Date());
        return save(loanIou);
    }

}
